//
//  GenericityVC.swift
//  swiftDemo
//
//  Created by yaqiang bi on 2017/3/31.
//  Copyright © 2017年 毕小强. All rights reserved.
//

import UIKit

class GenericityVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        var someInt = 3,anotherInt = 4
        swapTwoValues(&someInt, &anotherInt)
        print("交换后:\(someInt)  \(anotherInt)")
        
        var someStr = "hello",anotherStr = "world"
        swapTwoValues(&someStr, &anotherStr)
        print("交换后:\(someStr)  \(anotherStr)")
        
        var stackOfStrings = Stack<String>()
        stackOfStrings.push(item: "1")
        stackOfStrings.push(item: "2")
        stackOfStrings.push(item: "3")
        print(stackOfStrings.pop())
        print(stackOfStrings.topItem ?? "栈中没有值")
        
       print(findInde(array: [1,2,3,4,5,6,7], 1) ?? -1)
        
        // Do any additional setup after loading the view.
    }


    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

//MARK:泛型函数 类型形式参数B
func swapTwoValues<B>(_ a:inout B,_ b:inout B){
    let temporarya = a
    a = b
    b = temporarya
}

//MARK:泛型类型
struct Stack<Element> :Container{
    var items = [Element]()
    mutating func push(item:Element){
        items.append(item)
    }
    
    mutating func pop()->Element{
        return items.removeLast()
    }
    mutating func append(item: Element) {
        self.push(item: item)
    }
    var count: Int{
        return items.count
    }
    subscript(i:Int)->Element{
        return items[i]
    }
}

//MARK:扩展一个泛型类型
extension Stack{
    var topItem:Element?{
        return items.isEmpty ? nil:items[items.count-1]
    }
}

//MARK:类型约束
func findInde<T:Equatable>(array:[T],_ valueToFind:T) -> Int?{
    for (index,value) in array.enumerated() {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

//MARK:关联类型 associatedtype
protocol Container{
    associatedtype itemType
    mutating func append(item:itemType)
    var count:Int{get}
    subscript(i:Int)->itemType{get}
}

//MARK:泛型where语句 where写在函数体后边
func allItemMatch<C1:Container,C2:Container>(_ someContainer:C1,_ anotherContainer:C2)->Bool where C1.itemType == C2.itemType,C1.itemType:Equatable{
    if someContainer.count != anotherContainer.count {
        return false
    }
    
    for i in 0..<someContainer.count{
        if someContainer[i] != anotherContainer[i]{
            return false
        }
    }
    return true
}





